﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Net;

namespace EyeOfTheWorld
{
    // DIRECTED GRAPH WITH WEIGHTLESS EDGES
    public class Oracle
    {
        public string Reveal(string root, int depth, int namesLevel)
        {
            Page rootPage = Database.Instance.allPages[root];
            List<List<Page>> pagesLeveled = new List<List<Page>>();
            const string unvisited = "unvisited";
            const string visited = "visited";
            const string processed = "processed";
            rootPage.State = visited;
            rootPage.Number = 0;

            StringBuilder nodes = new StringBuilder();
            StringBuilder edges = new StringBuilder();
            pagesLeveled.Add(new List<Page>());
            pagesLeveled[0].Add(rootPage);
            int count = 1;
            //nodes.Append(string.Format("{0}|{1}|{2}|", rootPage.Address, rootPage.Address, 0));

            for (int level = 0; level < depth; )
            {
                List<Page> currentLevel = pagesLeveled[level];
                pagesLeveled.Add(new List<Page>());
                level++;
                foreach (Page page in currentLevel)
                {
                    int connectionsCount = 0;
                    foreach (Link link in page.Connections)
                    {
                        Page pageDestination = link.ToPage;
                        //edges.Append(string.Format("{0}|{1}|1|", page.Number, link.ToPage.Number));
                        if (pageDestination.State == unvisited)
                        {
                            connectionsCount++;
                            pageDestination.Number = count++;
                            edges.Append(string.Format("{0}|{1}|", page.Number, pageDestination.Number));
                            pageDestination.State = visited;
                            pagesLeveled[level].Add(link.ToPage);
                        }
                    }
                    page.State = processed;
                    if (connectionsCount > namesLevel)
                    {
                        if (level == 1)
                        {
                            page.Label = page.Address;
                        }
                        else if (depth > 1 && level - 1 < depth)
                        {
                            page.Label = page.Address;
                        }
                    }
                    //nodes.Append(string.Format("{0}|{1}|{2}|", page.Address, connectionsCount > 20 ? page.Address : "", level));
                }
            }

            for (int level = 0; level < pagesLeveled.Count; level++)
            {
                foreach (Page page in pagesLeveled[level])
                {
                    nodes.Append(string.Format("{0}|{1}|{2}|", page.Address, page.Label, level));
                }
            }
            return string.Format("{0}${1}", nodes.ToString().TrimEnd('|'), edges.ToString().TrimEnd('|'));
        }
    }
}
